package cxm.proj.capturer;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;

import Ice.Communicator;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.os.Environment;
import android.provider.MediaStore;
import android.util.Log;
import android.view.View;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemClickListener;
import android.widget.ArrayAdapter;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ListView;
import android.widget.TextView;
import cap.Image;

import com.baidu.location.BDLocation;
import com.baidu.location.BDLocationListener;
import com.baidu.location.LocationClient;
import com.baidu.location.LocationClientOption;

import cxm.lib.smack.ConnectManager;
import cxm.lib.smack.ConnectTaskResultHandle;
import cxm.lib.smack.UserException;
import cxm.lib.smack.UserManager;
import cxm.lib.util.MyLog;

public class MainActivity extends Activity {
	private static final int REQUEST_IMAGE_CAPTURE = 1;
	
	private Button button = null;
	private Button refreshButton = null;
	private ListView listView = null;
	private LinearLayout linearLayout = null;
	private Communicator _communicator = null;
	private boolean isLogin = false;
	private boolean isTakePhoto = false;
	private LocationClient mLocationClient = null;
	private BDLocationListener myListener = new MyLocationListener();
	private String locationString = "unknown";
	private Image image = null;
	
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        
        this.button = (Button)this.findViewById(R.id.button);
        this.refreshButton = (Button)this.findViewById(R.id.refresh_button);
        this.linearLayout = (LinearLayout)this.findViewById(R.id.linearLayout);
        this.listView = (ListView)this.findViewById(R.id.listview);
        this.listView.setOnItemClickListener(new OnItemClickListener() {
			@Override
			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long arg3) {
				String imageName = ((TextView)arg1).getText().toString();
				MyLog.Log(MyLog.Level.Info, "Try to get image " + imageName);
				
				// get text image
				cap.ReceiverPrx hello = createProxy();
				try {
					image = hello.downloadImage(
							UserManager.getInstance().getLoginName(), imageName);
					if (null == image || null == image.imageData) {
						MyLog.Log(MyLog.Level.Error, "Get image failed");
						return;
					}
					MainActivity.this.runOnUiThread(new Runnable() {
						@Override
						public void run() {
							linearLayout.setBackgroundDrawable(new BitmapDrawable(
									BitmapFactory.decodeByteArray(image.imageData,
											0, image.imageData.length)));
						}
					});
				} catch (Exception e) {
					MyLog.Log(MyLog.Level.Error, "Cannot get image data: " + e);
				}
			}
        });
        // prepare ice connection
        CaptureApp app = (CaptureApp)getApplication();
        app.setCommunicatorCallback(new CaptureApp.CommunicatorCallback()
        {
            public void onCreate(final Ice.Communicator communicator)
            {
            	Log.d("MainActivity", "Communicator onCreate");

            	_communicator = communicator;
            	prepareComplete();
            }

            public void onError(final Ice.LocalException ex)
            {
            	Log.d("MainActivity", "Communicator onError");
            }

            public void onWait()
            {
            	Log.d("MainActivity", "Communicator onWait");
            }
        });
    }
    
    @Override
    public void onResume() {
    	super.onResume();
    	// to skip on resume for taking photo
    	if (isTakePhoto) {
    		isTakePhoto = false;
    		return;
    	}

		this.mLocationClient = new LocationClient(this.getApplicationContext());
		this.mLocationClient.registerLocationListener(this.myListener);
		LocationClientOption option = new LocationClientOption();
		option.setOpenGps(true);
		option.setAddrType("all");//返回的定位结果包含地址信息
		option.setCoorType("bd09ll");//返回的定位结果是百度经纬度,默认值gcj02
		option.setScanSpan(5000);//设置发起定位请求的间隔时间为5000ms
		option.disableCache(true);//禁止启用缓存定位
		option.setPoiNumber(5);    //最多返回POI个数   
		option.setPoiDistance(1000); //poi查询距离        
		option.setPoiExtraInfo(true); //是否需要POI的电话和地址等详细信息        
		this.mLocationClient.setLocOption(option);
		
    	// login
    	this.isLogin = false;
    	this._communicator = null;
    	try {
			UserManager.getInstance().login(new ConnectTaskResultHandle() {
				@Override
				public void taskResultHandle(int result, Object tag) {
					MyLog.Log(MyLog.Level.Info, "Login result: " + result);
					isLogin = true;
					prepareComplete();
				}
			}, null);
		} catch (UserException e) {
			e.printStackTrace();
		}
    }
    
    @Override
    public void onPause() {
    	super.onPause();
    	// to skip on resume for taking photo
    	if (isTakePhoto)
    		return;
    	
    	try {
    		this.mLocationClient.stop();
    		UserManager.release();
    		ConnectManager.release();
    	} catch (Exception e) {
    		e.printStackTrace();
    	}
    }
	
	public void onClick(View view) {
		this.mLocationClient.start();
		if (!this.mLocationClient.isStarted()) {
			MyLog.Log(MyLog.Level.Error, "start failed");
			return;
		}
		int res = this.mLocationClient.requestLocation();
		MyLog.Log(MyLog.Level.Info, "Request res: " + res);
		
		this.button.setEnabled(false);
		this.refreshButton.setEnabled(false);
	}
	
	public void onRefreshClick(View view) {
		this.listView.setAdapter(new ArrayAdapter<String>(this,
				R.drawable.listview_text_adapter, getData()));
	}
	
	private List<String> getData() {
		List<String> data = new ArrayList<String>();
		try {
			cap.ReceiverPrx hello = createProxy();
			String []imageList = hello.getImageList(UserManager.getInstance().getLoginName());
			for (int i = 0; i < imageList.length; i++)
				data.add(imageList[i]);
		} catch (Exception e) {
			MyLog.Log(MyLog.Level.Error, "Cannot get image list: " + e);
		}
        
        return data;
	}
	
	@Override
	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
	    if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
	        Bundle extras = data.getExtras();
	        Bitmap imageBitmap = (Bitmap) extras.get("data");
	        this.linearLayout.setBackgroundDrawable(new BitmapDrawable(imageBitmap));
	        
	        // save file
	        String file_path = Environment.getExternalStorageDirectory().getAbsolutePath() + 
                    "/image.png";
	        File file = new File(file_path);
	        try {
	        	FileOutputStream fOut = new FileOutputStream(file);
	        	imageBitmap.compress(Bitmap.CompressFormat.PNG, 85, fOut);
	        	fOut.flush();
	        	fOut.close();
	        } catch (Exception e) {
	        	Log.d("MainActivity", "Error: " + e);
	        }

	        // upload
	        ByteArrayOutputStream stream = new ByteArrayOutputStream();
	        imageBitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
	        byte[] byteArray = stream.toByteArray();
			this.uploadImage(byteArray);
	    }
	}
    
	private void prepareComplete() {
		if (null == this._communicator || !this.isLogin)
			return;
		
        runOnUiThread(new Runnable()
        {
            public void run()
            {
            	button.setEnabled(true);
            	refreshButton.setEnabled(true);
            }
        });
	}
	
	private void uploadImage(byte []data)
    {
        cap.ReceiverPrx hello = createProxy();

    	Image image = new Image();
    	image.imageData = data;
    	image.location = this.locationString;
    	
        try {
            int res = hello.uploadImage(UserManager.getInstance().getLoginName(), image);
            if (0 != res)
            	MyLog.Log(MyLog.Level.Error, "Cannot upload image: " + res);
        } catch(Ice.LocalException ex) {
            Log.d("MainActivity", "Error with " + ex);
        }
        
        try {
        	String []imageList = hello.getImageList("cxm");
        	Log.d("MainActivity", "Images: " + imageList[0] + " " + imageList[1]);
        } catch (Exception e) {
        	Log.e("MainActivity", "error " + e);
        }
    }
    
    private cap.ReceiverPrx createProxy()
    {
    	if (null == this._communicator)
    		return null;

    	String host = "192.168.0.127";
        String s = "capture:tcp -h " + host + " -p 10000";
    	Ice.ObjectPrx prx = _communicator.stringToProxy(s);
        prx = prx.ice_twoway().ice_timeout(-1).ice_secure(false);
        return cap.ReceiverPrxHelper.uncheckedCast(prx);
    }
    
    public class MyLocationListener implements BDLocationListener {
		@Override
		public void onReceiveLocation(BDLocation location) {
			if (location == null)
				return ;
			MyLog.Log(MyLog.Level.Info, String.format("Get location %f and %f",
					location.getLatitude(), location.getLongitude()));

			// stop locationclient
			MainActivity.this.mLocationClient.stop();

			MainActivity.this.runOnUiThread(new Runnable() {
				@Override
				public void run() {
					MainActivity.this.button.setEnabled(true);
					refreshButton.setEnabled(true);
				}
			});
			Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
		    if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
		        startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
		        isTakePhoto = true;
		    }
			
			locationString = location.getAddrStr();
		}

		@Override
		public void onReceivePoi(BDLocation arg0) {
			MyLog.Log(MyLog.Level.Info, "onReceivePoi");
		}
	}
}
